// Package sys
// @Link  https://github.com/bufanyun/hotgo
// @Copyright  Copyright (c) 2025 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License  https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.15.11
package sys

import (
	"context"
	"fmt"
	"hotgo/internal/consts"
	"hotgo/internal/dao"
	"hotgo/internal/library/dict"
	"hotgo/internal/library/hgorm"
	"hotgo/internal/library/hgorm/handler"
	"hotgo/internal/model"
	"hotgo/internal/model/entity"
	"hotgo/internal/model/input/sysin"
	"hotgo/internal/service"

	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/grand"
)

type sSysStore struct{}

func NewSysStore() *sSysStore {
	return &sSysStore{}
}

func init() {
	service.RegisterSysStore(NewSysStore())
	dict.RegisterFunc("storeOption", "门店选项", service.SysStore().Option)
}

// Model 门店管理ORM模型
func (s *sSysStore) Model(ctx context.Context, option ...*handler.Option) *gdb.Model {
	return handler.Model(dao.Store.Ctx(ctx), option...)
}

// List 获取门店管理列表
func (s *sSysStore) List(ctx context.Context, in *sysin.StoreListInp) (list []*sysin.StoreListModel, totalCount int, err error) {
	mod := s.Model(ctx)

	// 字段过滤
	mod = mod.FieldsPrefix(dao.Store.Table(), sysin.StoreListModel{})
	mod = mod.Fields(hgorm.JoinFields(ctx, sysin.StoreListModel{}, &dao.AdminMember, "adminMember"))
	mod = mod.Fields()

	// 关联表字段
	mod = mod.LeftJoinOnFields(dao.AdminMember.Table(), dao.Store.Columns().BusinessId, "=", dao.AdminMember.Columns().Id)

	// 查询门店名称
	if in.Name != "" {
		mod = mod.WhereLike(dao.Store.Columns().Name, "%"+in.Name+"%")
	}

	if in.Phone != "" {
		mod = mod.WhereLike(dao.Store.Columns().Phone, "%"+in.Phone+"%")
	}

	// 分页
	mod = mod.Page(in.Page, in.PerPage)

	// 排序
	mod = mod.OrderDesc(dao.Store.Columns().Id)

	// 查询数据
	if err = mod.ScanAndCount(&list, &totalCount, false); err != nil {
		err = gerror.Wrap(err, "获取门店列表失败，请稍后重试！")
		return
	}
	return
}

// Edit 修改/新增门店管理
func (s *sSysStore) Edit(ctx context.Context, in *sysin.StoreEditInp) (err error) {
	return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {

		// 坐标
		in.Location = gdb.Raw(fmt.Sprintf("POINT(%f, %f)", in.Lng, in.Lat))

		// 查询手机号是否注册商户帐号
		mb, err := service.AdminMember().GetByMobile(ctx, in.Phone, []int{consts.RoleStore})
		if err != nil {
			err = gerror.Wrap(err, "操作门店失败，请稍后重试！")
			return
		}

		// 手机号未注册，创建商户帐号
		if mb == nil {
			mbID, err := dao.AdminMember.Ctx(ctx).Data(&entity.AdminMember{
				Avatar:   "https://imgs.ynz666.com/test/2025/01/08/MzQ3MGEyMWE3NzYwNmM4N2Y2M2VjNGRkZWJhNGNhMzA=.png", // 默认头像
				DeptId:   114,                                                                                        // 休闲吧
				Salt:     grand.S(12),
				Pid:      0,
				Level:    1,
				Tree:     " ",
				Status:   consts.StatusEnabled,
				Mobile:   in.Phone,
				RoleId:   consts.RoleStore,
				RealName: in.Name,
			}).OmitEmptyData().InsertAndGetId()
			if err != nil {
				return gerror.Wrap(err, "新增门店失败，请稍后重试！")
			}
			mb = &entity.AdminMember{
				Id: mbID,
			}
		}

		// 修改
		if in.Id > 0 {
			// 获取门店信息
			oldStore := &entity.Store{}
			if err = s.Model(ctx).WherePri(in.Id).Scan(oldStore); err != nil {
				err = gerror.Wrap(err, "修改门店失败，请稍后重试！")
			}

			// 修改门店信息
			if _, err = s.Model(ctx).
				Fields(sysin.StoreUpdateFields{}).
				WherePri(in.Id).Data(in).Update(); err != nil {
				err = gerror.Wrap(err, "修改门店失败，请稍后重试！")
			}

			// 修改手机号
			if oldStore.Phone != in.Phone {

				// 查询手机号用户
				oldmb, err2 := service.AdminMember().GetByMobile(ctx, oldStore.Phone, []int{consts.RoleStore})
				if err2 != nil {
					err = gerror.Wrap(err2, "修改门店失败，请稍后重试！")
					return
				}

				// 帐号删除管理门店
				if oldmb != nil {
					_, err = dao.StoreMember.Ctx(ctx).
						Where(dao.StoreMember.Columns().StoreId, oldStore.Id).
						Where(dao.StoreMember.Columns().MemberId, oldmb.Id).Delete()
					if err != nil {
						return gerror.Wrap(err, "修改门店失败，请稍后重试！")
					}
				}

				// 帐号添加管理门店
				_, err = dao.StoreMember.Ctx(ctx).Data(entity.StoreMember{
					StoreId:  oldStore.Id,
					MemberId: mb.Id,
					IsAdmin:  1,
				}).Insert()
				if err != nil {
					return gerror.Wrap(err, "修改门店失败，请稍后重试！")
				}
			}

			// 修改关联的商户
			if oldStore.BusinessId != in.BusinessId {
				if oldStore.BusinessId > 0 {
					// 商户删除管理门店
					_, err = dao.StoreMember.Ctx(ctx).
						Where(dao.StoreMember.Columns().StoreId, oldStore.Id).
						Where(dao.StoreMember.Columns().MemberId, oldStore.BusinessId).Delete()
					if err != nil {
						return gerror.Wrap(err, "修改门店失败，请稍后重试！")
					}
				}

				// 商户添加管理门店
				if in.BusinessId > 0 {
					// 商户添加管理门店
					_, err = dao.StoreMember.Ctx(ctx).Data(entity.StoreMember{
						StoreId:  oldStore.Id,
						MemberId: in.BusinessId,
						IsAdmin:  1,
					}).Insert()
					if err != nil {
						return gerror.Wrap(err, "修改门店失败，请稍后重试！")
					}
				}
			}

			return
		}

		// 新增门店
		id, err := s.Model(ctx, &handler.Option{FilterAuth: false}).
			Fields(sysin.StoreInsertFields{}).
			Data(in).OmitEmptyData().InsertAndGetId()
		if err != nil {
			err = gerror.Wrap(err, "新增门店失败，请稍后重试！")
		}

		// 设置门店旧ID
		//if _, err = s.Model(ctx, &handler.Option{FilterAuth: false}).
		//	Fields(dao.Store.Columns().OldId).
		//	WherePri(id).Data(entity.Store{
		//	OldId: id,
		//}).Update(); err != nil {
		//	err = gerror.Wrap(err, "新增门店失败，请稍后重试！")
		//	return
		//}

		// 帐号添加管理门店
		_, err = dao.StoreMember.Ctx(ctx).Data(entity.StoreMember{
			StoreId:  id,
			MemberId: mb.Id,
			IsAdmin:  1,
		}).Insert()
		if err != nil {
			return gerror.Wrap(err, "新增门店失败，请稍后重试！")
		}

		// 商户添加管理门店
		if in.BusinessId > 0 {
			_, err = dao.StoreMember.Ctx(ctx).Data(entity.StoreMember{
				StoreId:  id,
				MemberId: in.BusinessId,
				IsAdmin:  1,
			}).Insert()
			if err != nil {
				return gerror.Wrap(err, "新增门店失败，请稍后重试！")
			}
		}
		return
	})
}

// Delete 删除门店管理
func (s *sSysStore) Delete(ctx context.Context, in *sysin.StoreDeleteInp) (err error) {

	return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
		store := entity.Store{}
		err = dao.Store.Ctx(ctx).WherePri(in.Id).Scan(&store)
		if err != nil {
			err = gerror.Wrap(err, "获取门店信息，请稍后重试！")
			return
		}

		if store.BusinessId > 0 {
			// 商户删除管理门店
			_, err = dao.StoreMember.Ctx(ctx).
				Where(dao.StoreMember.Columns().StoreId, store.Id).Delete()
			if err != nil {
				return gerror.Wrap(err, "删除门店失败，请稍后重试！")
			}
		}
		if _, err = s.Model(ctx).WherePri(in.Id).Unscoped().Delete(); err != nil {
			err = gerror.Wrap(err, "删除门店失败，请稍后重试！")
			return
		}
		return
	})
}

// View 获取门店管理指定信息
func (s *sSysStore) View(ctx context.Context, in *sysin.StoreViewInp) (res *sysin.StoreViewModel, err error) {
	md := s.Model(ctx)
	if in.Lng != 0 && in.Lat != 0 {
		md = md.Fields(gdb.Raw(fmt.Sprintf("ROUND(ST_Distance_Sphere(location, ST_GeomFromText('POINT(%f %f)')) / 1000, 1) as distance", in.Lng, in.Lat)))
	}
	if err = md.
		Fields(sysin.StoreViewModel{}).
		WherePri(in.Id).Scan(&res); err != nil {
		err = gerror.Wrap(err, "获取门店信息，请稍后重试！")
		return
	}
	return
}

// View 获取门店管理指定信息
func (s *sSysStore) ViewPhone(ctx context.Context, phone string) (res *sysin.StoreViewModel, err error) {
	if err = s.Model(ctx).Where("phone", phone).Scan(&res); err != nil {
		err = gerror.Wrap(err, "获取门店信息，请稍后重试！")
		return
	}
	return
}

func (s *sSysStore) Option(ctx context.Context) (opts []*model.Option, err error) {
	var models []*entity.Store
	if err = s.Model(ctx).Fields(dao.Store.Columns().Id, dao.Store.Columns().Name).OrderDesc(dao.Store.Columns().Id).Scan(&models); err != nil {
		err = gerror.Wrap(err, "获取门店列表失败，请稍后重试！")
		return
	}
	opts = make([]*model.Option, len(models))
	for k, store := range models {
		opts[k] = dict.GenHashOption(store.Id, store.Name)
	}
	return
}
